using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(C_BasicAttribute))]
[RequireComponent(typeof(C_FollowTarget))]
public class C_ShotSystem : C_Base
{
    int currentNumber = 0;
    Transform muzzlePosTran;
    CData_ShotSystem Data
    {
        get
        {
            return GetData<CData_ShotSystem>();
        }
    }

    C_BasicAttribute basicAttribute;
    C_FollowTarget followTarget;
    C_AnimationController animationController;


    string callbackFuncNames = "Shot";
    public override void OnAddComponent()
    {
        base.OnAddComponent();
        GetComponent<C_BasicAttribute>().OnAddComponent();
        GetComponent<C_FollowTarget>().OnAddComponent();
        componentManager.AddCallbackFuncName(callbackFuncNames);
    }
    public override void OnRemoveComponent()
    {
        base.OnRemoveComponent();
        componentManager.RemoveCallbackFuncName(callbackFuncNames);
    }
    public override void Equip(params Object[] args)
    {
        base.Equip();
        if (GetComponent<C_BasicAttribute>().isPlayer)
        {
            UISystem.Instance.UpdateWeaponBulletNumber(currentNumber, Data.totalNumber);
        }
    }
    public override void UnEquip(params Object[] args)
    {
        base.UnEquip();
    }
    private void Start()
    {
        basicAttribute = GetComponent<C_BasicAttribute>();
        followTarget = GetComponent<C_FollowTarget>();
        animationController = GetComponent<C_AnimationController>();
        muzzlePosTran = Instantiate(Data.muzzleGO, transform).GetComponent<Transform>();
        muzzlePosTran.localPosition = Data.muzzlePos;
        CloneData();
        Reload_();
    }

    private void Update()
    {
        
    }
    public virtual float GetAngle()
    {
        //Vector3 mouseScreenPos = followTarget.GetTargetPoint();
        //Vector3 dir = (mouseScreenPos - muzzlePosTran.position).normalized;
        //float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
        Vector3 dir = muzzlePosTran.right;
        float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
        return angle;
    }
    public void Reload()
    {
        SendMessage("CoolingReload", new object[] { Data.reloadTime * basicAttribute.GetHolderData().GetReloadReductionScale(), Data.reloadCount });
    }
    public virtual GameObject GetSolid(int index, Transform muzzlePosTran, float angle)
    {
        if (currentNumber > 0)
        {
            currentNumber--;
            if (basicAttribute.isPlayer)
            {
                UISystem.Instance.UpdateWeaponBulletNumber(currentNumber, Data.totalNumber);
            }
            if (currentNumber == 0 && Data.totalNumber > 0)
            {
                animationController?.SetAttackValid(false);
                Reload();
            }
            else if (currentNumber == 0 && Data.totalNumber == 0)
            {
                SendMessage("SetAttackValid", false);
            }
        }
        GameObject bullet = Instantiate(Data.solidList[index]);
        bullet.transform.parent = transform;
        bullet.transform.position = muzzlePosTran.position;
        bullet.transform.parent = GameObject.Find("EffectTran").transform;
        bullet.transform.Rotate(new Vector3(0, 0, angle));

        EffectSystem.Instance.AddEffectsTOGOByNames(basicAttribute.C_HolderGO, bullet, bullet.GetComponent<LogicalEffectManager>().initEffectNameList);

        return bullet;
    }
    public virtual void Shot()
    {
        int fireCount = Data.isContinueFire ? Data.continueCount : 1;
        fireCount = Data.isRandomContinue ? UnityEngine.Random.Range((int)Data.continueCountRandomRange.x, (int)Data.continueCountRandomRange.y + 1) : fireCount;
        StartCoroutine(Shot_Coro(fireCount));
    }

    public bool CanGetSolid()
    {
        return currentNumber > 0;
    }
    public void Reload_(int reloadCount = -1)
    {
        int count = 0;
        if (reloadCount == -1)
        {
            count = Mathf.Min(Data.numberPerOneClip, Data.totalNumber);
            count = Mathf.Min(count, Data.numberPerOneClip - currentNumber);
        }
        else
        {
            count = Mathf.Min(Mathf.Min(reloadCount, Data.numberPerOneClip - currentNumber), Data.totalNumber);
            count = Mathf.Min(count, Data.numberPerOneClip - currentNumber);
        }
        currentNumber += count;
        Data.totalNumber -= count;
        animationController?.SetAttackValid(true);
        if (basicAttribute.isPlayer)
        {
            UISystem.Instance.UpdateWeaponBulletNumber(currentNumber, Data.totalNumber);
        }
        if (currentNumber < Data.numberPerOneClip)
        {
            SendMessage("CoolingReload", new object[] { Data.reloadTime * basicAttribute.GetHolderData().GetReloadReductionScale(), Data.reloadCount });
        }
    }
    IEnumerator Shot_Coro(int fireCount)
    {
        for (int i = 0; i < fireCount; i++)
        {
            int countPerOneContinue = Data.countPerOneContinue;
            countPerOneContinue = Data.isRandomCountPerOneContinue ? UnityEngine.Random.Range((int)Data.countPerOneContinueRandomRange.x, (int)Data.countPerOneContinueRandomRange.y + 1) : countPerOneContinue;
            for (int k = 0; k < countPerOneContinue; k++)
            {
                if (CanGetSolid())
                {
                    int index = UnityEngine.Random.Range(0, Data.solidList.Count);

                    float angle = GetAngle();
                    if (Data.isScatteringFire)
                    {
                        if (Data.isRandomScatter)
                        {
                            float scatterAngle = UnityEngine.Random.Range(Data.scatteringAngleRandomRange.x, Data.scatteringAngleRandomRange.y) * ((UnityEngine.Random.Range(0, 2) == 1) ? 1 : -1);
                            angle += scatterAngle;
                        }
                        else if (countPerOneContinue > 1)
                        {
                            float scatterAngle = -Data.scatteringAngle + k * Data.scatteringAngle * 2 / (countPerOneContinue - 1);
                            angle += scatterAngle;
                        }
                    }
                    GameObject solid = GetSolid(index, muzzlePosTran, angle);
                    if (Data.intervalTimePerOneCount > 0)
                    {
                        yield return new WaitForSeconds(Data.intervalTimePerOneCount / basicAttribute.GetHolderData().GetAttackSpeedScale());
                    }
                }
                else
                {
                    yield break;
                }
            }
            if (Data.intervalTimePerOneContinue > 0)
            {
                yield return new WaitForSeconds(Data.intervalTimePerOneContinue / basicAttribute.GetHolderData().GetAttackSpeedScale());
            }
        }
        SendMessage("CoolingAttack", new object[] { Data.attackCoolingTime / basicAttribute.GetHolderData().GetAttackSpeedScale(), Data.isDrawbolt && CanGetSolid() ? Data.drawBoltTime * basicAttribute.GetHolderData().GetReloadReductionScale() : 0 });
    }
}
